import random
import time

from django.db import transaction

from util.ailpay import AliPaySDK
from util.Myredis import myredis
from util.Mytoken import mytoken
from django.db.models import Q, F
from django.shortcuts import render
from rest_framework.viewsets import ModelViewSet
from rest_framework.views import APIView
from rest_framework.response import Response
from zhxy import models, serzhxy
# Create your views here.

import os
from dashscope import Generation


class Outletlist(APIView):
    '''营业点列表'''

    def get(self, request):
        outlets = models.Outlet.objects.all()
        ser = serzhxy.OutletSerializer(outlets, many=True)
        return Response({"msg": "请求成功", "data": ser.data, "code": 200}, )


class OutletAdd(APIView):
    '''添加营业点'''

    def post(self, request):
        name = request.data.get("name")
        address = request.data.get("address")
        outlet1 = models.Outlet.objects.filter(name=name, address=address)
        if outlet1:
            return Response({"msg": "该店铺已存在", "data": "", "code": 200} )
        else:
            models.Outlet.objects.create(name=name, address=address)
            return Response({"msg": "添加成功", "data": "", "code": 200})


class OutletDel(APIView):
    '''删除营业点'''

    def post(self, request):
        id = request.data.get("id")
        name = request.data.get("name")
        address = request.data.get("address")
        outlet1 = models.Outlet.objects.filter(id=id, name=name, address=address).first()
        if outlet1:
            outlet1.delete()
            return Response({"msg": "删除成功", "data": "", "code": 200})
        else:
            return Response({"msg": "该店铺不存在", "data": "", "code": 200})


class OutletEdit(APIView):
    '''修改营业点状态'''

    def post(self, request):
        id = request.data.get("id")
        name = request.data.get("name")
        address = request.data.get("address")
        outlet1 = models.Outlet.objects.filter(id=id, name=name, address=address).first()
        if outlet1:
            outlet1.status = not outlet1.status
            return Response({"msg": "修改成功", "data": "", "code": 200})


class GetOutlet(APIView):
    '''查询营业点'''

    def post(self, request):
        query = Q()
        name = request.data.get("name")
        address = request.data.get("address")
        if name:
            query &= Q(name__icontains=name)
        if address:
            query &= Q(address__icontains=address)
        outlets = models.Outlet.objects.filter(query)
        ser = serzhxy.OutletSerializer(outlets, many=True)
        return Response({"msg": "请求成功", "data": ser.data, "code": 200})


class OutletDetail(APIView):
    '''营业点详情'''

    def get(self, request, pk):
        outlet = models.Outlet.objects.filter(id=pk).first()
        ser = serzhxy.OutletSerializer(outlet)
        return Response({"msg": "请求成功", "data": ser.data, "code": 200})


class Equipmentlist(APIView):
    '''营业点设备列表'''

    def get(self, request):
        query = Q()
        oid = request.query_params.get("oid")
        floor = request.query_params.get("floor")
        query &= Q(oid=oid)
        if floor:
            query &= Q(floor=floor)
        equipments = models.Equipment.objects.filter(query)
        ser = serzhxy.EquipmentSerializer(equipments, many=True)
        return Response({"msg": "请求成功", "data": ser.data, "code": 200})


class EquipmentDetail(APIView):
    '''设备详情'''

    def get(self, request, pk):
        equipment = models.Equipment.objects.filter(id=pk).first()
        ser = serzhxy.EquipmentSerializer(equipment)
        return Response({"msg": "请求成功", "data": ser.data, "code": 200})


class EquipmentAdd(APIView):
    '''设备添加'''

    def post(self, request):
        name = request.data.get("name")
        eid = request.data.get("eid")
        type = request.data.get("type")
        floor = request.data.get("floor")
        oid = request.data.get("oid")
        equipment1 = models.Equipment.objects.filter(eid=eid).first()
        if equipment1:
            return Response({"msg": "该设备已存在", "data": "", "code": 200})
        else:
            models.Equipment.objects.create(name=name, eid=eid, type=type, floor=floor, oid_id=oid)
            return Response({"msg": "添加成功", "data": "", "code": 200})


class EquipmentEdit(APIView):
    '''设备状态修改'''

    def post(self, request):
        id = request.data.get("id")
        eid = request.data.get("eid")
        equipment1 = models.Equipment.objects.filter(id=id, eid=eid).first()
        if equipment1:
            equipment1.status = not equipment1.status
            return Response({"msg": "修改成功", "data": "", "code": 200})
        else:
            return Response({"msg": "该设备不存在", "data": "", "code": 200})


class EquipmentDel(APIView):
    '''设备删除'''

    def post(self, request):
        id = request.data.get("id")
        equipment1 = models.Equipment.objects.filter(id=id).first()
        if equipment1:
            equipment1.delete()
            return Response({"msg": "删除成功", "data": "", "code": 200})


class SendMes(APIView):
    '''发送验证码'''

    def post(self, request):
        phone = request.data.get("phone")
        if phone:
            code = random.randint(1000, 9999)
            myredis.set_time_str(phone, 120, code)
            return Response({"msg": "发送成功", "data": code, "code": 200})
        else:
            return Response({"msg": "请输入手机号", "data": "", "code": 201})


class Login(APIView):
    '''登录/注册并登录'''

    def post(self, request):
        phone = request.data.get("phone")
        code = request.data.get("code")
        phone1 = models.User.objects.filter(phone=phone).first()
        if phone1:  # 有该用户
            if myredis.get_str(phone) == str(code):  # 验证码正确
                payload = {"userid": phone1.id, "username": phone1.name}
                user_token = mytoken.gettoken(payload)
                return Response(
                    {"msg": "登录成功", "data": {'token': user_token, 'userid': phone1.id, 'username': phone1.name},
                     "code": 200})
            else:
                return Response({"msg": "验证码错误", "data": "", "code": 201})
        else:  # 没有该用户,则创建
            if myredis.get_str(phone) == str(code):
                models.User.objects.create(phone=phone, name='zh'+phone+'x')
                phone = models.User.objects.filter(phone=phone).first()
                payload = {"userid": phone.id, "username": phone.name}
                user_token = mytoken.gettoken(payload)
                return Response(
                    {"msg": "登录成功", "data": {'token': user_token, 'userid': phone.id, 'username': phone.name},
                     "code": 200})
            else:
                return Response({"msg": "验证码错误", "data": "", "code": 201})


class UserInfo(APIView):
    '''获取用户信息'''

    def get(self, request):
        userid = request.query_params.get("userid")
        user = models.User.objects.filter(id=userid).first()
        if user:
            ser = serzhxy.UserSerializer(user)
            return Response({"msg": "请求成功", "data": ser.data, "code": 200})
        else:
            return Response({"msg": "请求失败", "data": "", "code": 400})


class UserUpdate(APIView):
    '''修改用户信息'''

    def post(self, request):
        userid = request.data.get("userid")
        if not userid:
            return Response({"error": "User ID is required"})

        try:
            user = models.User.objects.get(id=userid)
        except models.User.DoesNotExist:
            return Response({"error": "User not found"})

        # 构建要更新的字段字典
        update_fields = {}
        for field in ["name", "score", "img", "balance", "coupon"]:
            if field in request.data:
                update_fields[field] = request.data[field]

        # 更新用户信息
        for key, value in update_fields.items():
            setattr(user, key, value)
        user.save()

        # 返回成功响应（可选）
        return Response({"success": "修改成功"})


class Couponlist(APIView):
    '''获取优惠券列表'''

    def get(self, request):
        coupons = models.Coupon.objects.all()
        ser = serzhxy.CouponSerializer(coupons, many=True)
        return Response({"msg": "请求成功", "data": ser.data, "code": 200})


class Couponadd(APIView):
    '''获取优惠券'''

    def post(self, request):
        userid = request.data.get("userid")
        couponid = request.data.get("couponid")
        if userid and couponid:
            models.UserCoupon.objects.create(user_id=userid, coupon_id=couponid)
            return Response({"msg": "获取成功", "data": "", "code": 200})
        else:
            return Response({"msg": "获取失败", "data": "", "code": 400})

class UserCoupon(APIView):
    '''用户优惠券'''
    def get(self, request):
        userid = request.query_params.get("userid")
        user=models.UserCoupon.objects.filter(user_id=userid)
        ser=serzhxy.UserCouponSerializer(user,many=True)
        return Response({"msg": "请求成功", "data": ser.data, "code": 200})
def setordernum():
    return 'ZH' + str(time.time()).replace('.', '') + str(random.randint(1000, 9999)) + 'X'


class CreateOrder(APIView):
    '''创建订单'''

    def post(self, request):
        userid = request.data.get("userid")
        equipid = request.data.get("equipid")
        couponid = request.data.get("couponid")
        score = request.data.get("score")
        outlet= request.data.get("outlet")
        request_service = request.data.get("request_service")
        cope_with = float(request.data.get("cope_with"))
        ordernum = setordernum()
        if userid and equipid:
            userscore = models.User.objects.filter(id=userid).first().score
            if couponid:
                coupon = models.UserCoupon.objects.filter(coupon_id=couponid).first()
                if coupon:
                    if coupon.status:
                        pay = cope_with - coupon.coupon.price
                        if score and userscore >= int(score):  # 使用了积分和优惠券
                            pay1 = pay - int(score) / 10
                            models.Orderfg.objects.create(sponsor_id=userid, equip_id=equipid, ordernum=ordernum,
                                                          request_service=request_service, status='待支付',
                                                          usedcoupon_id=couponid,outlet_id=outlet,
                                                          cope_with=cope_with, usedscore=int(score), pay=pay1)
                            return Response({"msg": "创建订单成功", "data": ordernum, "code": 200})
                        else:  # 没有使用积分,使用了优惠券
                            models.Orderfg.objects.create(sponsor_id=userid, equip_id=equipid, ordernum=ordernum,
                                                          request_service=request_service, status='待支付',outlet_id=outlet,
                                                          usedcoupon_id=couponid, cope_with=cope_with, pay=pay)
                            return Response({"msg": "创建订单成功", "data": ordernum, "code": 200})
                    else:
                        return Response({"msg": "优惠券已使用", "data": '', "code": 400})
                else:
                    return Response({"msg": "优惠券不存在", "data": '', "code": 400})
            elif score and userscore >= int(score):
                pay = cope_with - int(score) / 10
                models.Orderfg.objects.create(sponsor_id=userid, equip_id=equipid, request_service=request_service,
                                              status='待支付', ordernum=ordernum,outlet_id=outlet,
                                              usedscore=int(score), cope_with=cope_with, pay=pay)
                return Response({"msg": "创建订单成功", "data": ordernum, "code": 200})
            else:
                models.Orderfg.objects.create(sponsor_id=userid, equip_id=equipid, request_service=request_service,outlet_id=outlet,
                                              status='待支付', cope_with=cope_with, pay=cope_with, ordernum=ordernum)
                return Response({"msg": "创建订单成功", "data": ordernum, "code": 200})
        else:
            return Response({"msg": "用户或设备不存在", "data": ordernum, "code": 400})


class OrderList(APIView):
    '''订单列表'''

    def get(self, request):
        userid = request.query_params.get("userid")
        status=request.query_params.get('status')
        if status and status != '':
            order = models.Orderfg.objects.filter(sponsor_id=userid,status=status).all()
            ser = serzhxy.OrderfgSerializer(order, many=True)
            return Response({"msg": "请求成功", "data": ser.data, "code": 200})
        order = models.Orderfg.objects.filter(sponsor_id=userid).all()
        ser = serzhxy.OrderfgSerializer(order, many=True)
        return Response({"msg": "请求成功", "data": ser.data, "code": 200})


class OrderDetail(APIView):
    '''订单详情'''

    def get(self, request):
        ordernum = request.query_params.get("ordernum")
        order = models.Orderfg.objects.filter(ordernum=ordernum).first()
        ser = serzhxy.OrderfgSerializer(order)
        return Response({"msg": "请求成功", "data": ser.data, "code": 200})


class Orderlink(APIView):
    '''订单支付链接'''

    def post(self, request):
        ordernum = request.data.get("ordernum")
        order = models.Orderfg.objects.filter(ordernum=ordernum).first()
        if order:
            if order.status == '待支付':
                ali = AliPaySDK()
                link = ali.page_pay(out_trade_no=ordernum, total_amount=order.pay, subject=order.request_service)
                return Response({"msg": "请求成功", "data": link, "code": 200})
            else:
                return Response({"msg": "订单已支付或取消", "data": "", "code": 400})
        else:
            return Response({"msg": "订单不存在", "data": "", "code": 400})



class OrderPay(APIView):
    '''订单支付成功后的回调函数'''

    @transaction.atomic
    def get(self, request):
        try:
            data = request.query_params.dict()
            alipay = AliPaySDK()
            success = alipay.check_sign(data)
            if success:
                ordernum = data.get('out_trade_no')
                order = models.Orderfg.objects.filter(ordernum=ordernum).first()
                if order:
                    user = models.User.objects.filter(id=order.sponsor_id).first()
                    coupon = order.usedcoupon
                    score = order.usedscore
                    if coupon:
                        models.UserCoupon.objects.filter(id=coupon.id).update(status=False)
                    if score:
                        models.User.objects.filter(id=user.id).update(score=F('score') - score)
                    order.status = '进行中'
                    order.save()

                    # 假设这里使用了异步任务或消息队列来处理后续逻辑
                    # 例如，发送一个任务到 Celery 来检查订单状态并在必要时更新它

                    # 这里只是模拟返回成功响应
                    ascore = order.pay * 0.01  # 注意：这里假设 order.pay 是已支付的金额
                    user.score += ascore  # 注意：这里只是为了演示，实际上应该使用 F 表达式来避免竞态条件
                    # 但由于我们在事务中，且只是示例，所以这样写也可以
                    # 在生产环境中，应该避免在事务中直接修改然后立即查询同一对象，除非使用 F 表达式或其他同步机制

                    # 注意：下面的代码实际上不会被执行，因为我们已经假设使用了异步处理
                    # 而且，直接修改 user 对象并不会反映到数据库中，除非再次调用 save()
                    # 但由于我们已经在事务中修改了 order，且这里只是示例，所以保留这段注释掉的代码以说明意图
                    # if order.status != '已取消':  # 注意：这里的检查实际上在异步任务中执行
                    #     order.status = '已完成'
                    #     order.save()
                    #     user.save()  # 在实际代码中，这里应该使用异步更新或确保事务的一致性

                    # 由于我们假设使用了异步处理，这里直接返回成功响应
                    ser = serzhxy.OrderfgSerializer(order)
                    return Response({"msg": "请求成功，订单状态已更新为进行中，后续处理将异步进行", "data": ser.data, "code": 200})
                else:
                    return Response({"msg": "订单不存在", "data": "", "code": 400})
            else:
                return Response({"msg": "签名验证失败", "data": "", "code": 400})
        except Exception as e:
            return Response({"msg": "请求失败", "data": str(e), "code": 500})


class Upload(APIView):
    def post(self, request):
        img = request.FILES.getlist('img')
        if img:
            img.name = img.name.split('.')[0] + '.jpg'
            with open('img/user/' + img.name, 'wb') as f:
                for chunk in img.chunks():
                    f.write(chunk)
            models.User.objects.filter(id=request.data.get('userid')).update(
                img='http://127.0.0.1:8000/zhxy/img/' + img.name)
            return Response({'code': 200, 'msg': '上传成功'})
        else:
            return Response({'code': 400, 'msg': '上传失败'})


class LLMess(APIView):
    '''LLM对话 搭载通义千问plus 人机对话'''

    def post(self, request):
        q = request.data.get("q")
        messages = [
            {'role': 'system', 'content': 'You are a helpful assistant.'},
            {'role': 'user', 'content': q}
        ]
        response = Generation.call(
            # 若没有配置环境变量，请用百炼API Key将下行替换为：api_key = "sk-xxx",
            api_key=os.getenv("DASHSCOPE_API_KEY"),
            model="qwen-plus",  # 模型列表：https://help.aliyun.com/zh/model-studio/getting-started/models
            messages=messages,
            result_format="message"
        )

        if response.status_code == 200:
            data = response.output.choices[0].message.content
            return Response({"msg": "请求成功", "data": data, "code": 200})
        else:
            print(f"HTTP返回码：{response.status_code}")
            print(f"错误码：{response.code}")
            print(f"错误信息：{response.message}")
            print("请参考文档：https://help.aliyun.com/zh/model-studio/developer-reference/error-code")
            return Response({"msg": "请求失败", "error": response.message, "code": 200}
)
